/*
 *DS1302使用程序
 *AUTHOR:
 *YIZHOU WANG 2021.MAY09
 *SUMMERY:
 *V0.1 为ARDUINO适配DS1302时钟芯片
 *
 */
#include<SPI.h>
//定义寄存器地址
#define SEC 0x80//秒寄存器
#define MIN 0x82//分寄存器
#define HOUR 0x84//时寄存器
#define DATE 0x86 //日期寄存器
#define MONTH 0x88//月寄存器
#define WEEK 0x8A//星期
#define YEAR 0x8C//年份，以上全为读取地址，若想写入，请在该地址或上0x01，该版程序已经将转换功能整合入函数中，所以使用时输入已经定义好的寄存器读取地址即可

#define RST PA3//reset引脚

//寄存器数据暂存
int SECDATA;
int MINDATA;
int HOURDATA;
int DATEDATA;
int MONTHDATA;
int WEEKDATA;
int YEARDATA;

char getReadAddr(int para)//将读取地址转换为写入地址
{
  return(para|0x01);
  }
  
void setup() {
  pinMode(RST,OUTPUT);
  SPI.begin();
  SPI.setBitOrder(LSBFIRST);//低位优先
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV16);//低速SPI，4.5MHZ
  //SS为PA4,SCK为PA5
  Serial.begin(9600);
}

  
char ReadFromDS1302(char addr)//从DS1302的目标寄存器中读取数据
{
  char TargetAddr=addr;//令写入地址转换为读取地址
  char ResultDat=0x00;
  digitalWrite(RST,HIGH);//RST脚拉高
  for(int i=0;i<8;i++)
  {
    digitalWrite(CLK,LOW);
    if(TargetAddr&0x01==1)//先LSB再HSB，此处先传递目标地址
    {
      digitalWrite(DAT,HIGH);//数据脚拉高
      }
      else
      {
        digitalWrite(DAT,LOW);//数据脚拉低
        }
        TargetAddr=TargetAddr>>1;//右移一位
        digitalWrite(CLK,HIGH);//时钟拉高，令DS1302接收数据
        delayMicroseconds(5);        
    }
    delayMicroseconds(5);
    pinMode(DAT,INPUT);
    for(int i=0;i<8;i++)//读取数据，主机提供时钟信号
    {
      digitalWrite(CLK,HIGH);
      delayMicroseconds(5);
      digitalWrite(CLK,LOW);
      delayMicroseconds(5);
      if(digitalRead(DAT)==HIGH)
      {
        ResultDat=ResultDat|0x01;
        }
         else
         {
          ResultDat=ResultDat;
          }
        ResultDat=ResultDat<<1;      
      }
    digitalWrite(RST,LOW);//RST脚拉高
    return(ResultDat);
  }
void loop() {
  SECDATA=ReadFromDS1302(SEC);
  MINDATA=ReadFromDS1302(MIN);
  HOURDATA=ReadFromDS1302(HOUR);
  DATEDATA=ReadFromDS1302(DATE);
  MONTHDATA=ReadFromDS1302(MONTH);
  WEEKDATA=ReadFromDS1302(WEEK);
  YEARDATA=ReadFromDS1302(YEAR); 

  Serial.println(SECDATA);
  Serial.println(MINDATA);
  Serial.println(HOURDATA);
  Serial.println(DATEDATA);
  Serial.println(MONTHDATA);
  Serial.println(WEEKDATA);
  Serial.println(YEARDATA); 

}
